package com.erp.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.erp.common.enums.DeleteEnum;
import com.erp.common.exception.BaseBizException;
import com.erp.common.response.ListVo;
import com.erp.common.utils.BeanUtils;
import com.erp.user.entity.UserRoles;
import com.erp.user.entity.Users;
import com.erp.user.mapper.UsersMapper;
import com.erp.user.request.*;
import com.erp.user.response.UsersDetailInfoResp;
import com.erp.user.response.UsersInfoResp;
import com.erp.user.response.UsersSearchInfoResp;
import com.erp.user.service.UserRolesService;
import com.erp.user.service.UsersService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.Set;


/**
 * @author shensong
 * @program machining_system.v1.0.0
 * @description  服务实现类
 * @date 2022/12/21 16:49:24
 */
@Service("usersService")
public class UsersServiceImpl extends ServiceImpl<UsersMapper, Users> implements UsersService {

    @Autowired
    private UserRolesService userRolesService;

    @Override
    public ListVo<List<UsersInfoResp>> index(UsersPageReq request) {
        LambdaQueryWrapper<Users> queryWrapper = Wrappers.lambdaQuery();
        if (Objects.nonNull(request)) {
            queryWrapper.eq(Objects.nonNull(request.getUid()),Users::getUid, request.getUid());
            queryWrapper.eq(StringUtils.isNotBlank(request.getUsername()),Users::getUsername, request.getUsername());
            queryWrapper.eq(StringUtils.isNotBlank(request.getPassword()),Users::getPassword, request.getPassword());
            queryWrapper.eq(StringUtils.isNotBlank(request.getToken()),Users::getToken, request.getToken());
            queryWrapper.eq(StringUtils.isNotBlank(request.getJobNum()),Users::getJobNum, request.getJobNum());
            queryWrapper.eq(StringUtils.isNotBlank(request.getName()),Users::getName, request.getName());
            queryWrapper.eq(StringUtils.isNotBlank(request.getSalt()),Users::getSalt, request.getSalt());
            queryWrapper.eq(StringUtils.isNotBlank(request.getMobile()),Users::getMobile, request.getMobile());
            queryWrapper.eq(Objects.nonNull(request.getIsEnabled()),Users::getIsEnabled, request.getIsEnabled());
            queryWrapper.eq(Objects.nonNull(request.getRevision()),Users::getRevision, request.getRevision());
            queryWrapper.eq(Objects.nonNull(request.getGmtCreate()),Users::getGmtCreate, request.getGmtCreate());
            queryWrapper.eq(Objects.nonNull(request.getGmtModified()),Users::getGmtModified, request.getGmtModified());
        }
        queryWrapper.eq(Users::getIsDeleted, DeleteEnum.NO.getCode());
        queryWrapper.orderByDesc(Users::getUid);
        IPage<Users> data = this.queryPage(request.getPageNum(), request.getPageSize(), queryWrapper);
        if (Objects.nonNull(data) && CollectionUtils.isNotEmpty(data.getRecords())) {
            List<UsersInfoResp> usersListResponse = BeanUtils.copyObjects(data.getRecords(), UsersInfoResp.class);
            return new ListVo<>(usersListResponse, data.getTotal(), data.getSize(), data.getCurrent());
        }

        return new ListVo<>();
    }

    @Override
    public Boolean store(UsersAddReq request) {
        Set<Long> roleIds = request.getRoleIds();
        Users entity = BeanUtils.copyProperties(request, Users.class);
        Boolean status = this.save(entity);

        if(status){
            return updateUserRoles(entity.getUid(), roleIds);
        }

        return status;
    }

    @Override
    public Boolean update(UsersUpdateReq request) {
        Users users = this.getById(request.getUid());
        if(Objects.isNull(users)){
            throw new BaseBizException("没有数据");
        }
        Set<Long> roleIds = request.getRoleIds();
        Users entity = BeanUtils.copyProperties(request, Users.class);
        Boolean status = this.updateById(entity);

        if(status){
            return updateUserRoles(entity.getUid(), roleIds);
        }

        return status;
    }

    @Override
    public Boolean destroy(UsersDeleteReq request) {
        Users users = this.getById(request.getUid());
        if(Objects.isNull(users)){
            throw new BaseBizException("没有数据");
        }
        LambdaUpdateWrapper<Users> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.set(Users::getIsDeleted, DeleteEnum.YES.getCode()).eq(Users::getUid, request.getUid());
        Boolean status = this.update(updateWrapper);

        if(status){
            return updateUserRoles(request.getUid(), null);
        }

        return status;
    }

    @Override
    public UsersInfoResp show(UsersInfoReq request) {
        LambdaQueryWrapper<Users> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(Users::getUid, request.getUid());
        queryWrapper.eq(Users::getIsDeleted, DeleteEnum.NO.getCode());
        Users entity = this.getOne(queryWrapper);
        return Objects.nonNull(entity) ? BeanUtils.copyProperties(entity, UsersInfoResp.class) : null;
    }

    @Override
    public Boolean approve(UsersApproveReq request) {
        Users entity = BeanUtils.copyProperties(request, Users.class);
        return this.updateById(entity);
    }

    @Override
    public Boolean enabled(UsersStatusReq request) {
        Users entity = this.getById(request.getUid());
        if(Objects.isNull(entity)){
            return false;
        }
        if(Objects.equals(entity.getIsEnabled(),1)){
            entity.setIsEnabled(0);
        }else{
            entity.setIsEnabled(1);
        }
        return this.updateById(entity);
    }

    @Override
    public List<UsersInfoResp> option(UsersListReq request) {
        LambdaQueryWrapper<Users> queryWrapper = Wrappers.lambdaQuery();
        if (Objects.nonNull(request)) {
            queryWrapper.eq(Objects.nonNull(request.getUid()), Users::getUid, request.getUid());
            queryWrapper.eq(StringUtils.isNotBlank(request.getUsername()), Users::getUsername, request.getUsername());
            queryWrapper.eq(StringUtils.isNotBlank(request.getPassword()), Users::getPassword, request.getPassword());
            queryWrapper.eq(StringUtils.isNotBlank(request.getToken()), Users::getToken, request.getToken());
            queryWrapper.eq(StringUtils.isNotBlank(request.getJobNum()), Users::getJobNum, request.getJobNum());
            queryWrapper.eq(StringUtils.isNotBlank(request.getName()), Users::getName, request.getName());
            queryWrapper.eq(StringUtils.isNotBlank(request.getSalt()), Users::getSalt, request.getSalt());
            queryWrapper.eq(StringUtils.isNotBlank(request.getMobile()), Users::getMobile, request.getMobile());
            queryWrapper.eq(Objects.nonNull(request.getIsEnabled()), Users::getIsEnabled, request.getIsEnabled());
            queryWrapper.eq(Objects.nonNull(request.getRevision()), Users::getRevision, request.getRevision());
            queryWrapper.eq(Objects.nonNull(request.getIsDeleted()), Users::getIsDeleted, request.getIsDeleted());
            queryWrapper.eq(Objects.nonNull(request.getGmtCreate()), Users::getGmtCreate, request.getGmtCreate());
            queryWrapper.eq(Objects.nonNull(request.getGmtModified()), Users::getGmtModified, request.getGmtModified());
        }

        queryWrapper.orderByDesc(Users::getUid);
        List<Users> data = this.list(queryWrapper);
        return CollectionUtils.isNotEmpty(data) ? BeanUtils.copyObjects(data, UsersInfoResp.class) : Lists.newArrayList();
    }

    @Override
    public List<UsersSearchInfoResp> search(UsersSearchReq request) {
        LambdaQueryWrapper<Users> queryWrapper = Wrappers.lambdaQuery();
        if (Objects.nonNull(request)) {
                queryWrapper.eq(Objects.nonNull(request.getUid()), Users::getUid, request.getUid());
                queryWrapper.eq(StringUtils.isNotBlank(request.getUsername()), Users::getUsername, request.getUsername());
                queryWrapper.eq(StringUtils.isNotBlank(request.getPassword()), Users::getPassword, request.getPassword());
                queryWrapper.eq(StringUtils.isNotBlank(request.getToken()), Users::getToken, request.getToken());
                queryWrapper.eq(StringUtils.isNotBlank(request.getJobNum()), Users::getJobNum, request.getJobNum());
                queryWrapper.eq(StringUtils.isNotBlank(request.getName()), Users::getName, request.getName());
                queryWrapper.eq(StringUtils.isNotBlank(request.getSalt()), Users::getSalt, request.getSalt());
                queryWrapper.eq(StringUtils.isNotBlank(request.getMobile()), Users::getMobile, request.getMobile());
                queryWrapper.eq(Objects.nonNull(request.getIsEnabled()), Users::getIsEnabled, request.getIsEnabled());
                queryWrapper.eq(Objects.nonNull(request.getRevision()), Users::getRevision, request.getRevision());
                queryWrapper.eq(Objects.nonNull(request.getGmtCreate()), Users::getGmtCreate, request.getGmtCreate());
                queryWrapper.eq(Objects.nonNull(request.getGmtModified()), Users::getGmtModified, request.getGmtModified());
        }
        queryWrapper.eq(Users::getIsDeleted, request.getIsDeleted());
        queryWrapper.orderByDesc(Users::getUid);
        List<Users> data = this.list(queryWrapper);
        return CollectionUtils.isNotEmpty(data) ? BeanUtils.copyObjects(data, UsersSearchInfoResp.class) : Lists.newArrayList();
    }

    @Override
    public UsersDetailInfoResp detail(UsersInfoReq request) {
        return BeanUtils.copyProperties(this.show(request), UsersDetailInfoResp.class);
    }

    private IPage<Users> queryPage(Long pageNum, Long pageSize, Wrapper<Users> queryWrapper) {
        IPage<Users> selectPage = new Page<>();
        selectPage.setCurrent(pageNum);
        selectPage.setSize(pageSize);

        IPage<Users> page = this.baseMapper.selectPage(selectPage, queryWrapper);
        return page;
    }

    private Boolean updateUserRoles(Long uid, Set<Long> roleIds){
        LambdaQueryWrapper<UserRoles> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(UserRoles::getUid, uid);
        Boolean s = userRolesService.remove(queryWrapper);

        if(CollectionUtils.isNotEmpty(roleIds)){
            List<UserRoles> userRolesList = Lists.newArrayList();
            roleIds.forEach(roleId->{
                UserRoles userRolesEntity = new UserRoles();
                userRolesEntity.setRoleId(roleId);
                userRolesEntity.setUid(uid);
                userRolesList.add(userRolesEntity);
            });

            return userRolesService.saveBatch(userRolesList);
        }

        return s;
    }
}
